﻿/*!
 * file : gridx.js
 * gitee : 
 * github : 
 * author : 百小僧/MonkSoul
 * version : v3.0.0
 * create time : 2018.06.15
 * update time : 2018.06.22
 */

; !(function (over, win, slf) {
    var Gridx = {
        version: '3.0.0',
        gridxlist: {},
        layout: 'auto',
        defaults: {
            id: '',
            key: '',
            colModels: [],
            multiSelect: false,
            rowNumber: true,
            dataType: 'json',
            dataSource: 'local',
            data: [],
            url: '',
            type: "GET",
            params: {},
            events: {
                row: {
                    onclick: function (rowid) {
                    },
                    ondblclick: function (rowid) {
                    },
                    oncontextmenu: function (rowid) {
                    }
                },
                async: {
                    beforeSend: function () {
                    },
                    success: function (text, xml) {
                    },
                    error: function (status, e) {
                    },
                    complete: function () {
                    }
                }
            },
            pager: false,
            pageSizeOptions: [30, 50, 100, 200, 500],
            pageSize: 100,
            pageIndex: 1,
            groups: {}
        },
        groupDefaults: {
            label: "",
            align: 'left',
            length: 0
        },
        colDefaults: {
            name: '',
            label: '',
            width: 100,
            align: 'left',
            resizable: true,
            hidden: false,
            freeze: false,
            sortable: true,
            cls: '',
            map: '',
            format: null
        },
        init: function (target, options) {
            var that = this,
                config = ObjectExtend({}, that.defaults, options || {}),
                grid = {};
            if (!config.id) {
                console.error("id不能为空且唯一");
                return;
            }
            if (that.gridxlist[config.id]) return that.gridxlist[config.id];
            if (!Utils.isDom(target)) {
                console.error("target不是有效的HTMLElement元素")
            }

            grid.id = config.id;
            grid.gridxDomId = "gridx-" + config.id;
            grid.target = target;
            grid.key = config.key;
            grid.multiSelect = config.multiSelect;
            grid.rowNumber = config.rowNumber;
            grid.dataSource = config.dataSource;
            grid.dataType = config.dataType;
            grid.url = config.url;
            grid.type = config.type;
            grid.params = config.params || {};
            grid.events = config.events;
            grid.pager = config.pager;
            grid.pageSizeOptions = config.pageSizeOptions || [30, 50, 100, 200, 500, 1000];
            grid.pageIndex = config.pageIndex || 1;
            grid.pageSize = config.pageSize || 100;
            var groups = config.groups || {};
            for (var key in groups) {
                groups[key] = ObjectExtend({}, that.groupDefaults, groups[key] || {});
            }
            grid.groups = groups;
            grid.isGroupHead = Object.getOwnPropertyNames(groups).length > 0;
            grid.rowids = [];
            grid.colModels = [];
            var colModels = config.colModels || [];
            for (var i = 0, len = colModels.length; i < len; i++) {
                grid.colModels.push(ObjectExtend({}, that.colDefaults, colModels[i] || {}));
            }
            that.gridxlist[config.id] = grid;
            grid.scatterCols = that.getScatterCols(config.id);

            var docfmt = document.createDocumentFragment();
            var panel = document.createElement("div");
            panel.classList.add("gridx-panel");
            panel.classList.add("gridx-flexbox");
            panel.classList.add("gridx-flexcol");
            panel.id = "gridx-" + config.id;
            that.bindPanelEvent(panel);
            docfmt.appendChild(panel);

            var shade = document.createElement("div");
            shade.classList.add("gridx-shade");
            panel.appendChild(shade);
            var shadeText = document.createElement("div");
            shadeText.classList.add('gridx-load-text');
            shadeText.innerText = "正在处理数据中，请稍等...";
            shade.appendChild(shadeText);

            var head = document.createElement("div");
            head.classList.add("gridx-head");
            head.classList.add("gridx-flexbox");
            head.classList.add("gridx-flexrow");
            panel.appendChild(head);

            var headLeftFix = document.createElement("div");
            headLeftFix.classList.add("gridx-left-fix");
            head.appendChild(headLeftFix);
            headLeftFix.appendChild(that.createTable("thead"));

            var headScroll = document.createElement("div");
            headScroll.classList.add("gridx-head-scroll");
            headScroll.classList.add("gridx-flexauto");
            head.appendChild(headScroll);
            headScroll.appendChild(that.createTable("thead"));

            var headRightFix = document.createElement("div");
            headRightFix.classList.add("gridx-right-fix");
            head.appendChild(headRightFix);
            headRightFix.appendChild(that.createTable("thead"));

            var body = document.createElement("div");
            body.classList.add("gridx-body");
            body.classList.add("gridx-flexauto");
            body.classList.add("gridx-flexbox");
            body.classList.add("gridx-flexrow");
            panel.appendChild(body);

            var bodyLeftFix = document.createElement("div");
            bodyLeftFix.classList.add("gridx-left-fix");
            body.appendChild(bodyLeftFix);
            bodyLeftFix.appendChild(that.createTable("tbody"));

            var bodyScroll = document.createElement("div");
            bodyScroll.classList.add("gridx-body-scroll");
            bodyScroll.classList.add("gridx-flexauto");
            body.appendChild(bodyScroll);
            bodyScroll.appendChild(that.createTable("tbody"));

            var bodyRightFix = document.createElement("div");
            bodyRightFix.classList.add("gridx-right-fix");
            body.appendChild(bodyRightFix);
            bodyRightFix.appendChild(that.createTable("tbody"));

            if (config.pager === true) {
                var foot = document.createElement("div");
                foot.classList.add("gridx-foot");
                panel.appendChild(foot);
                foot.appendChild(that.createPageBar(config.id));
            }

            target.appendChild(docfmt);

            bodyScroll.onscroll = function (e) {
                e = e || window.event;
                e.stopPropagation();
                headScroll.style.marginLeft = - this.scrollLeft + "px";
                bodyLeftFix.style.marginTop = - this.scrollTop + "px"
                bodyRightFix.style.marginTop = - this.scrollTop + "px"
            };

            that.createHeadContent(config.id);
            if (config.dataSource === "local") {
                that.loadTip(config.id);
                setTimeout(function () {
                    that.createBodyContent(config.id, config.data);
                    that.closeLoadTip(config.id);
                }, 0);
            }
            else if (config.dataSource === "remote") {
                that.loadRemoteData(config.id);
            }
            return grid;
        },
        loadTip: function (id) {
            var that = this, grid = that.gridxlist[id];
            if (grid) {
                var panel = document.querySelector("#" + grid.gridxDomId);
                panel.querySelector(".gridx-shade").setAttribute("data-handle", "1");
            }
        },
        closeLoadTip: function (id) {
            var that = this, grid = that.gridxlist[id];
            if (grid) {
                var panel = document.querySelector("#" + grid.gridxDomId);
                panel.querySelector(".gridx-shade").removeAttribute("data-handle");
            }
        },
        getScatterCols: function (id, reallyCol) {
            var that = this, grid = that.gridxlist[id];
            var leftfixs = [], scrollarea = [], rightfixs = [];
            if (grid) {
                var colModes = grid.colModels;
                for (var i = 0, len = colModes.length; i < len; i++) {
                    var col = colModes[i];
                    if (col.freeze === true) leftfixs.push(col);
                    else break;
                }
                var colReverseModels = colModes.reverse();
                for (var i = 0, len = colReverseModels.length; i < len; i++) {
                    var col = colReverseModels[i];
                    if (col.freeze === true) rightfixs.unshift(col);
                    else break;
                }
                scrollarea = Utils.array_difference(Utils.array_difference(colModes, leftfixs), rightfixs).reverse();
                if (reallyCol !== true) {
                    if (grid.multiSelect === true) {
                        leftfixs.unshift({
                            name: '__check-panel__'
                        });
                    }
                    if (grid.rowNumber === true) {
                        leftfixs.unshift({
                            name: '__row-number__'
                        });
                        rightfixs.push({
                            name: '__row-number__'
                        });
                    }
                }
            }
            return {
                "left-fix": leftfixs,
                "head-scroll": scrollarea,
                "right-fix": rightfixs
            };
        },
        createPageBar: function (id) {
            var that = this, grid = that.gridxlist[id];
            var pageBar = document.createElement("div");
            pageBar.classList.add("gridx-page-bar");
            if (grid) {
                var pageRight = document.createElement("div");
                pageRight.classList.add("gridx-page-right");
                pageBar.appendChild(pageRight);
                var pageTotalLabel = document.createElement("div");
                pageTotalLabel.classList.add("gridx-label");
                pageTotalLabel.innerHTML = "当前第 <span class='gridx-span' id='gridx-pageIndex'>1</span> / <span class='gridx-span' id='gridx-pageCount'>3</span> 页，每页 <div class='gridx-pagesize-options' id='gridx-pageSize'></div> 条，共 <span class='gridx-span' id='gridx-total'>1000</span> 条";
                pageRight.appendChild(pageTotalLabel);
                var pageSizeOptionsPanel = pageRight.querySelector(".gridx-pagesize-options");
                var pageSizeOptions = grid.pageSizeOptions;
                var select = document.createElement("select");
                select.classList.add("gridx-select");
                pageSizeOptionsPanel.appendChild(select);
                for (var i = 0, len = pageSizeOptions.length; i < len; i++) {
                    var pageSizeOption = pageSizeOptions[i];
                    var option = document.createElement("option");
                    option.classList.add("gridx-option");
                    option.value = pageSizeOption;
                    option.innerText = pageSizeOption;
                    grid.pageSize === pageSizeOption && (option.setAttribute("selected", "selected"));
                    select.appendChild(option);
                }

                var pageCenter = document.createElement("div");
                pageCenter.classList.add("gridx-page-center");
                pageBar.appendChild(pageCenter);

                var firstLabel = document.createElement("div");
                firstLabel.classList.add("gridx-label");
                grid.pageIndex === 1 && (firstLabel.setAttribute("data-disabled", "1"));
                firstLabel.id = "gridx-page-first";
                firstLabel.innerText = "首页";
                pageCenter.appendChild(firstLabel);

                var prevLabel = document.createElement("div");
                prevLabel.classList.add("gridx-label");
                grid.pageIndex === 1 && (prevLabel.setAttribute("data-disabled", "1"));
                prevLabel.id = "gridx-page-prev";
                prevLabel.innerText = "上一页";
                pageCenter.appendChild(prevLabel);

                var nextLabel = document.createElement("div");
                nextLabel.classList.add("gridx-label");
                nextLabel.id = "gridx-page-next";
                nextLabel.innerText = "下一页";
                pageCenter.appendChild(nextLabel);

                var lastLabel = document.createElement("div");
                lastLabel.classList.add("gridx-label");
                lastLabel.id = "gridx-page-last";
                lastLabel.innerText = "尾页";
                pageCenter.appendChild(lastLabel);
            }
            return pageBar;
        },
        createTable: function (type) {
            var table = document.createElement("table");
            table.classList.add("gridx-table");
            table.setAttribute("cellspacing", "0");
            table.setAttribute("cellpadding", "0");
            table.setAttribute("border", "0");
            var child = document.createElement(type);
            child.classList.add("gridx-" + type);
            table.appendChild(child);
            return table;
        },
        createHeadScatterCols: function (id, cols) {
            var that = this, grid = that.gridxlist[id];
            var thead = document.createElement("thead");
            thead.classList.add("gridx-thead");
            if (grid) {
                var tr = document.createElement("tr");
                tr.classList.add("gridx-tr");
                thead.appendChild(tr);

                var groupTr = document.createElement("tr");
                groupTr.classList.add("gridx-tr");

                var totalGroupLength = 0, currentGroupIndex = 0;
                for (var i = 0, len = cols.length; i < len; i++) {
                    var col = cols[i];
                    if (/^__(.+)__$/.test(col.name)) {
                        var th = document.createElement("th");
                        var colName = col.name.replace(/__/g, "");
                        th.classList.add("gridx-th");
                        th.classList.add('gridx-th-' + colName);
                        th.setAttribute("align", "center");
                        grid.isGroupHead && (th.setAttribute("rowspan", "2"))
                        tr.appendChild(th);
                        switch (colName) {
                            case "row-number":
                                var text = document.createElement("div");
                                text.classList.add("gridx-text");
                                text.classList.add("gridx-user-select-none");
                                text.innerText = 0;
                                text.style.minWidth = "25px";
                                th.appendChild(text);
                                break;
                            case "check-panel":
                                var checkWrap = document.createElement("div");
                                checkWrap.classList.add("gridx-check-wrap");
                                checkWrap.style.width = "35px";
                                th.appendChild(checkWrap);
                                var checkbox = document.createElement("input");
                                checkbox.classList.add("gridx-checkbox");
                                checkbox.setAttribute("type", "checkbox");
                                checkbox.addEventListener("change", function (e) {
                                    that.setChecks(id, this.checked);
                                }, false);
                                checkWrap.appendChild(checkbox);
                                break;
                        }
                    }
                    else {
                        var th = document.createElement("th");
                        th.classList.add("gridx-th");
                        th.setAttribute("align", col.align);
                        th.setAttribute("title", col.label);
                        th.setAttribute("data-name", col.name);
                        col.hidden === true && (th.setAttribute("data-hidden", "1"));

                        if (grid.isGroupHead) {
                            var groupCol = grid.groups[col.name];
                            if (groupCol) {
                                totalGroupLength = groupCol.length;
                                currentGroupIndex = 1;
                                var groupTh = document.createElement("th");
                                groupTh.classList.add("gridx-th");
                                groupTh.setAttribute("align", groupCol.align);
                                groupTh.setAttribute("colspan", totalGroupLength);
                                var groupText = document.createElement("div");
                                groupText.classList.add("gridx-text");
                                groupText.classList.add("gridx-user-select-none");
                                groupText.innerText = groupCol.label;
                                groupTh.appendChild(groupText);
                                tr.appendChild(groupTh);

                                groupTr.appendChild(th);
                            }
                            else {
                                if (currentGroupIndex < totalGroupLength) {
                                    currentGroupIndex++;
                                    groupTr.appendChild(th);
                                }
                                else {
                                    totalGroupLength = 0;
                                    currentGroupIndex = 0;
                                    th.setAttribute("rowspan", "2");
                                    tr.appendChild(th);
                                }
                            }
                        }
                        else {
                            tr.appendChild(th);
                        }

                        var text = document.createElement("div");
                        text.classList.add("gridx-text");
                        text.classList.add("gridx-user-select-none");
                        text.innerText = col.label;
                        text.style.width = col.width + "px";
                        th.appendChild(text);

                        if (col.resizable === true) {
                            var resize = document.createElement("div");
                            resize.classList.add("gridx-resize");
                            th.appendChild(resize);
                        }
                        if (col.sortable === true) {
                            var sort = document.createElement("div");
                            sort.classList.add("gridx-sort");
                            sort.classList.add("gridx-flexbox");
                            sort.classList.add("gridx-flex-align-vertical");
                            sort.innerHTML = '<svg class="gridx-iconfont" aria-hidden="true"><use xlink:href="#gridx-icon-sort-down"></use></svg>';
                            th.appendChild(sort);
                        }
                    }
                }
                grid.isGroupHead && (thead.appendChild(groupTr));
            }
            return thead;
        },
        createHeadContent: function (id) {
            var that = this, grid = that.gridxlist[id];
            if (grid) {
                var head = document.querySelector("#" + grid.gridxDomId + " .gridx-head");
                var scatterCols = grid.scatterCols;
                for (var key in scatterCols) {
                    var table = head.querySelector(".gridx-" + key + " .gridx-table");
                    table.replaceChild(that.createHeadScatterCols(id, scatterCols[key]), table.firstElementChild);
                }
                head.parentNode.querySelector(".gridx-shade .gridx-load-text").style.top = head.offsetHeight + "px";
            }
        },
        bindPanelEvent: function (panel) {
            panel.addEventListener("mouseout", function (e) {
                var body = this.querySelector(".gridx-body");
                var childs = body.children;
                for (var i = 0, len = childs.length; i < len; i++) {
                    var child = childs[i];
                    var lastRow = child.querySelector(".gridx-tr[data-mouseover='1']");
                    lastRow && (lastRow.removeAttribute("data-mouseover"));
                }
            }, false);
        },
        setChecks: function (id, isCheck) {
            var that = this, grid = that.gridxlist[id];
            if (grid) {
                var body = document.querySelector("#" + grid.gridxDomId + " .gridx-body");
                Array.prototype.filter.call(body.children, function (child) {
                    var rows = child.querySelector(".gridx-table").rows;
                    for (var i = 0, len = rows.length; i < len; i++) {
                        var row = rows[i];
                        if (isCheck === true) {
                            if (!row.getAttribute("data-click")) {
                                row.setAttribute("data-click", "1");
                                if (child.classList.contains("gridx-left-fix")) {
                                    var checkbox = row.querySelector(".gridx-td-check-panel .gridx-checkbox");
                                    checkbox && (checkbox.checked = true);
                                }
                            }
                        }
                        else {
                            if (row.getAttribute("data-click")) {
                                row.removeAttribute("data-click");
                                if (child.classList.contains("gridx-left-fix")) {
                                    var checkbox = row.querySelector(".gridx-td-check-panel .gridx-checkbox");
                                    checkbox && (checkbox.checked = false);
                                }
                            }
                        }
                    }
                });
            }
        },
        setRowAttribute: function (id, tr, eventType) {
            var that = this, grid = that.gridxlist[id];
            if (grid) {
                var lastRow = tr.parentNode.querySelector(".gridx-tr[data-" + eventType + "='1']");
                if (lastRow && lastRow !== tr) {
                    if (grid.multiSelect !== true) {
                        lastRow.removeAttribute("data-" + eventType);
                        var checkbox = lastRow.querySelector(".gridx-td-check-panel .gridx-checkbox");
                        checkbox && (checkbox.checked = false);
                    }
                }
                if (eventType !== "mouseover") {
                    var isLeftFix = tr.parentNode.parentNode.parentNode.classList.contains("gridx-left-fix");
                    if (tr.getAttribute("data-click") === "1") {
                        if (isLeftFix && grid.multiSelect === true) {
                            tr.querySelector(".gridx-td-check-panel .gridx-checkbox").checked = false;
                        }
                        tr.removeAttribute("data-" + eventType);
                    }
                    else {
                        if (isLeftFix && grid.multiSelect === true) {
                            tr.querySelector(".gridx-td-check-panel .gridx-checkbox").checked = true;
                        }
                        tr.setAttribute("data-" + eventType, "1");
                    }
                }
                else {
                    tr.setAttribute("data-" + eventType, "1");
                }
            }
        },
        bindBodyTrEvent: function (id, tr, eventType) {
            var that = this, grid = that.gridxlist[id];
            if (grid) {
                tr.addEventListener(eventType, function (e) {
                    e = e || window.event;
                    var _tr = this;
                    var rowid = tr.getAttribute("data-rowid");
                    if (grid.events && grid.events.row && Utils.isFunction(grid.events.row["on" + eventType])) {
                        grid.events.row["on" + eventType](rowid);
                    }
                    if (eventType !== "dblclick") {
                        Array.prototype.filter.call(Utils.getNodeByClassName(_tr, "gridx-body").children, function (child) {
                            that.setRowAttribute(id, child.querySelector(".gridx-tr[data-rowid='" + rowid + "']"), eventType === "contextmenu" ? "click" : eventType);
                        });
                    }
                });
            }
        },
        createBodyScatterData: function (id, cols, data) {
            var that = this, grid = that.gridxlist[id];
            var tbody = document.createElement("tbody");
            tbody.classList.add("gridx-tbody");
            if (grid) {
                var rowids = grid.rowids;
                for (var i = 0, len = data.length; i < len; i++) {
                    var rowData = data[i];
                    if (rowids.length !== data.length) {
                        rowids.push(grid.key ? rowData[grid.key] : Utils.newGuid());
                    }
                    var tr = document.createElement("tr");
                    tr.classList.add("gridx-tr");
                    i % 2 === 0 && (tr.classList.add("gridx-tr-even"));
                    tr.setAttribute("data-rowid", rowids[i]);
                    tr.setAttribute("data-index", i + 1);
                    that.bindBodyTrEvent(id, tr, "mouseover");
                    that.bindBodyTrEvent(id, tr, "click");
                    that.bindBodyTrEvent(id, tr, "dblclick");
                    that.bindBodyTrEvent(id, tr, "contextmenu");
                    tbody.appendChild(tr);
                    for (var j = 0, len2 = cols.length; j < len2; j++) {
                        var col = cols[j];
                        if (/^__(.+)__$/.test(col.name)) {
                            var td = document.createElement("td");
                            var colName = col.name.replace(/__/g, "");
                            td.classList.add("gridx-td");
                            td.classList.add('gridx-td-' + colName);
                            td.setAttribute("align", "center");
                            tr.appendChild(td);
                            switch (colName) {
                                case "row-number":
                                    var text = document.createElement("div");
                                    text.classList.add("gridx-text");
                                    text.classList.add("gridx-user-select-none");
                                    text.innerText = i + 1;
                                    text.style.minWidth = "25px";
                                    td.appendChild(text);
                                    break;
                                case "check-panel":
                                    var checkWrap = document.createElement("div");
                                    checkWrap.classList.add("gridx-check-wrap");
                                    checkWrap.style.width = "35px";
                                    td.appendChild(checkWrap);
                                    var checkbox = document.createElement("input");
                                    checkbox.classList.add("gridx-checkbox");
                                    checkbox.setAttribute("type", "checkbox");
                                    checkWrap.appendChild(checkbox);
                                    break;
                            }
                        }
                        else {
                            var td = document.createElement("td");
                            td.classList.add("gridx-td");
                            td.setAttribute("align", col.align);
                            td.setAttribute("title", rowData[col.name] || "");
                            td.setAttribute("data-name", col.name);
                            td.setAttribute("data-value", rowData[col.name] || "");
                            col.cls && (td.classList.add(col.cls));
                            col.hidden === true && (td.setAttribute("data-hidden", "1"));
                            tr.appendChild(td);

                            var text = document.createElement("div");
                            text.classList.add("gridx-text");
                            var content = (col.map ? Utils.evalMap(rowData, col.map) : rowData[col.name]) || "";
                            if (col.format) {
                                if (Utils.isFunction(col.format)) {
                                    text.innerHTML = col.format(content);
                                }
                                else {
                                    text.innerHTML = col.format;
                                }
                            }
                            else text.innerHTML = content;
                            text.style.width = col.width + "px";
                            td.appendChild(text);
                        }
                    }
                }
            }
            return tbody;
        },
        createBodyContent: function (id, data) {
            var that = this, grid = that.gridxlist[id];
            if (grid) {
                var panel = document.querySelector("#" + grid.gridxDomId);
                var body = panel.querySelector("#" + grid.gridxDomId + " .gridx-body");
                var scatterCols = grid.scatterCols;
                for (var key in scatterCols) {
                    var table = body.querySelector(".gridx-" + (key === "head-scroll" ? "body-scroll" : key) + " .gridx-table");
                    table.replaceChild(that.createBodyScatterData(id, scatterCols[key], data), table.firstElementChild);
                }
                var head = panel.querySelector(".gridx-head");
                var leftRowNumber = head.querySelector(".gridx-left-fix .gridx-th-row-number>.gridx-text");
                var rightRowNumber = head.querySelector(".gridx-right-fix .gridx-th-row-number>.gridx-text");
                leftRowNumber.innerText = rightRowNumber.innerText = data.length;
            }
        },
        updatePageInfo: function (id, pageIndex, pageSize, pageCount, total) {
            var that = this, grid = that.gridxlist[id];
            if (grid) {
                if (grid.pager === true) {
                    var panel = document.querySelector("#" + grid.gridxDomId);
                    panel.setAttribute("data-pageIndex", pageIndex);
                    panel.setAttribute("data-pageSize", pageSize);
                    panel.setAttribute("data-pageCount", pageCount);
                    panel.setAttribute("data-total", total);

                    panel.querySelector("#gridx-pageIndex").innerText = pageIndex;
                    panel.querySelector("#gridx-pageCount").innerText = pageCount;
                    panel.querySelector("#gridx-total").innerText = total;
                    panel.querySelector("#gridx-pageSize .gridx-select").value = pageSize;
                }
            }
        },
        loadRemoteData: function (id, url, params) {
            var that = this, grid = that.gridxlist[id];
            if (grid) {
                var defaultData = ObjectExtend({}, grid.pager === true ? { pageIndex: grid.pageIndex, pageSize: grid.pageSize } : {}, grid.params);
                grid.params = ObjectExtend({}, defaultData, params || {});
                var panel = document.querySelector("#" + grid.gridxDomId);
                grid.rowids = [];
                Utils.ajax({
                    url: url ? url : grid.url,
                    type: grid.type,
                    data: grid.params,
                    async: true,
                    dataType: grid.dataType,
                    before: function () {
                        if (grid.events && grid.events.async && Utils.isFunction(grid.events.async["beforeSend"])) {
                            var reval = grid.events.async["beforeSend"]();
                            if (reval !== false) {
                                that.loadTip(id);
                            }
                            else return false;
                        }
                        else {
                            that.loadTip(id);
                        }
                    },
                    success: function (text, xml) {
                        try {
                            var rep = JSON.parse(text);
                            setTimeout(function () {
                                that.createBodyContent(id, rep.rows);
                                if (grid.pager === true) {
                                    that.updatePageInfo(id, rep.pageIndex, rep.pageSize, rep.pageCount, rep.total);
                                }
                                that.closeLoadTip(id);
                                if (grid.events && grid.events.async && Utils.isFunction(grid.events.async["success"])) {
                                    grid.events.async["success"](text, xml);
                                }
                            }, 0);
                        } catch (e) {
                            if (grid.events && grid.events.async && Utils.isFunction(grid.events.async["error"])) {
                                grid.events.async["error"](null, e);
                            }
                            that.closeLoadTip(id);
                        }
                    },
                    error: function (status) {
                        that.closeLoadTip(id);
                        if (grid.events && grid.events.async && Utils.isFunction(grid.events.async["error"])) {
                            grid.events.async["error"](status);
                        }
                    },
                    complete: function () {
                        if (grid.events && grid.events.async && Utils.isFunction(grid.events.async["complete"])) {
                            grid.events.async["complete"]();
                        }
                    }
                });
            }
        },
        getSelectRowId: function (id) {
            var that = this, grid = that.gridxlist[id];
            if (grid) {
                var panel = document.querySelector("#" + grid.gridxDomId);
                var row = panel.querySelector(".gridx-body-scroll .gridx-tbody .gridx-tr[data-click='1']");
                if (row) {
                    return row.getAttribute("data-rowid");
                }
                return null;
            }
        },
        getSelectRowData: function (id, rowid) {
            var that = this, grid = that.gridxlist[id], data = {};
            if (grid) {
                var scrollTd = document.querySelectorAll("#" + grid.gridxDomId + " .gridx-tr[data-rowid='" + rowid + "'] .gridx-td[data-value]");
                for (var i = 0, len = scrollTd.length; i < len; i++) {
                    var td = scrollTd[i];
                    var name = td.getAttribute("data-name");
                    var value = td.getAttribute("data-value");
                    data[name] = value;
                }
            }
            return data;
        }
    };

    var Utils = {
        isDom: function (obj) {
            return !!(obj && typeof window !== 'undefined' && (obj === window || obj.nodeType));
        },
        isFunction: function (func) {
            return func && Object.prototype.toString.call(func) === '[object Function]';
        },
        isJson: function (obj) {
            var isjson = (typeof (obj) == "object" && Object.prototype.toString.call(obj).toLowerCase() == "[object object]" && !obj.length);
            return isjson;
        },
        evalMap: function (object, map) {
            if (map.indexOf('.') > -1) {
                var arr = map.split(".");
                var value = object[arr[0]];
                if (value) {
                    for (var i = 1, len = arr.length; i < len; i++) {
                        value = value[arr[i]];
                        if (!value) break;
                    }
                }
                return value;
            }
            return object[map];
        },
        getNodeByClassName: function (node, className, parentWindow) {
            parentWindow = parentWindow || win;
            var that = this;
            if (node === parentWindow.document.body) {
                return null;
            }
            var cls = node.classList;
            if (cls.contains(className)) {
                return node;
            } else {
                return that.getNodeByClassName(node.parentNode, className);
            }
        },
        newGuid: function () {
            var guid = "";
            for (var i = 1; i <= 32; i++) {
                var n = Math.floor(Math.random() * 16.0).toString(16);
                guid += n;
                if ((i == 8) || (i == 12) || (i == 16) || (i == 20))
                    guid += "-";
            }
            return guid;
        },
        array_remove_repeat: function (a) {
            var r = [];
            for (var i = 0; i < a.length; i++) {
                var flag = true;
                var temp = a[i];
                for (var j = 0; j < r.length; j++) {
                    if (temp === r[j]) {
                        flag = false;
                        break;
                    }
                }
                if (flag) {
                    r.push(temp);
                }
            }
            return r;
        },
        array_difference: function (a, b) {
            var that = this;
            var clone = a.slice(0);
            for (var i = 0; i < b.length; i++) {
                var temp = b[i];
                for (var j = 0; j < clone.length; j++) {
                    if (temp === clone[j]) {
                        clone.splice(j, 1);
                    }
                }
            }
            return that.array_remove_repeat(clone);
        },
        getParams: function (data) {
            var arr = [];
            for (var param in data) {
                arr.push(encodeURIComponent(param) + '=' + encodeURIComponent(data[param]));
            }
            arr.push(('v=' + Math.random()).replace('.'));
            return arr.join('&');
        },
        ajax: function (options) {
            var that = this;
            options = options || {};
            options.type = (options.type || "GET").toUpperCase();
            options.dataType = options.dataType || 'json';
            options.async = options.async || true;
            var params = that.getParams(options.data);
            var xhr;
            if (window.XMLHttpRequest) {
                xhr = new XMLHttpRequest();
            } else {
                xhr = new ActiveXObject('Microsoft.XMLHTTP')
            }
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4) {
                    var status = xhr.status;
                    if (status >= 200 && status < 300) {
                        options.success && options.success(xhr.responseText, xhr.responseXML);
                    } else {
                        options.error && options.error(status);
                    }
                    options.complete && options.complete();
                }
            };
            if (options.type == 'GET') {
                var reval = options.before && options.before();
                if (reval !== false) {
                    xhr.open("GET", options.url + (options.url.indexOf("?") > -1 ? "&" : '?') + params, options.async);
                    xhr.send(null)
                }
            } else if (options.type == 'POST') {
                var reval = options.before && options.before();
                if (reval !== false) {
                    xhr.open('POST', options.url, options.async);
                    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
                    xhr.send(params);
                }
            }
        }
    };

    win.gridx = {
        init: function (target, options) {
            return Gridx.init(target, options);
        },
        loadData: function (id, url, params) {
            Gridx.loadRemoteData(id, url, params);
        },
        getSelectRowId: function (id) {
            return Gridx.getSelectRowId(id);
        },
        getSelectRowData: function (id, rowid) {
            return Gridx.getSelectRowData(id, rowid);
        }
    };
})(top, window, self);

; !(function (global) {
    var extend,
        _extend,
        _isObject;
    _isObject = function (o) {
        return Object.prototype.toString.call(o) === '[object Object]';
    };
    _extend = function self(destination, source) {
        var property;
        for (property in destination) {
            if (destination.hasOwnProperty(property)) {
                if (_isObject(destination[property]) && _isObject(source[property])) {
                    self(destination[property], source[property]);
                }
                if (source.hasOwnProperty(property)) {
                    continue;
                } else {
                    source[property] = destination[property];
                }
            }
        }
    };
    extend = function () {
        var arr = arguments,
            result = {},
            i;
        if (!arr.length)
            return {};
        for (i = arr.length - 1; i >= 0; i--) {
            if (_isObject(arr[i])) {
                _extend(arr[i], result);
            }
        }
        arr[0] = result;
        return result;
    };
    global.ObjectExtend = extend;
})(window);

; !(function (window) {
    var svgSprite = '<svg><symbol id="gridx-icon-sort-down" viewBox="0 0 1024 1024"><path d="M803.65625 668.76875V287.28125a27.675 27.675 0 0 0-8.04375-20.08125 28.29375 28.29375 0 0 0-20.1375-8.325 28.575 28.575 0 0 0-28.125 28.40625v381.4875l-112.66875-111.375a27.73125 27.73125 0 0 0-39.9375 0 27.675 27.675 0 0 0 0 39.4875l159.35625 157.6125a27.73125 27.73125 0 0 0 19.6875 8.38125 28.9125 28.9125 0 0 0 20.25-7.3125l159.4125-157.5a27.16875 27.16875 0 0 0 0-39.6 28.29375 28.29375 0 0 0-39.99375 0l-109.8 110.25zM90.125 704.375h450.45c15.58125 0 28.18125 12.4875 28.18125 27.84375a28.0125 28.0125 0 0 1-28.125 27.84375H90.125a28.0125 28.0125 0 0 1-28.125-27.84375c0-15.35625 12.6-27.84375 28.125-27.84375z m0-222.75h281.53125c15.58125 0 28.125 12.4875 28.125 27.84375a28.0125 28.0125 0 0 1-28.125 27.84375H90.18125A28.0125 28.0125 0 0 1 62 509.46875c0-15.35625 12.6-27.84375 28.125-27.84375zM540.63125 258.875H90.18125c-15.58125 0-28.125 12.4875-28.125 27.84375s12.54375 27.84375 28.125 27.84375h450.45c15.58125 0 28.125-12.4875 28.125-27.84375a28.0125 28.0125 0 0 0-28.125-27.84375z"  ></path></symbol><symbol id="gridx-icon-sort-up" viewBox="0 0 1024 1024"><path d="M220.34375 355.23125L220.34374999 736.71875a27.675 27.675 0 0 0 8.04375002 20.08125 28.29375 28.29375 0 0 0 20.13749999 8.325 28.575 28.575 0 0 0 28.125-28.40625l0-381.4875 112.66875 111.375a27.73125 27.73125 0 0 0 39.9375 0 27.675 27.675 0 0 0-1e-8-39.4875l-159.35624999-157.61250001a27.73125 27.73125 0 0 0-19.6875-8.38124999 28.9125 28.9125 0 0 0-20.25 7.3125l-159.4125 157.5a27.16875 27.16875 0 0 0 0 39.59999999 28.29375 28.29375 0 0 0 39.99375 0l109.8-110.24999999zM933.875 319.625l-450.45 0c-15.58124999 0-28.18125-12.4875-28.18125-27.84375a28.0125 28.0125 0 0 1 28.125-27.84375L933.875 263.9375a28.0125 28.0125 0 0 1 28.12499999 27.84375c0 15.35625-12.6 27.84375-28.12499999 27.84375z m0 222.75l-281.53125 0c-15.58124999 0-28.125-12.4875-28.125-27.84375a28.0125 28.0125 0 0 1 28.125-27.84375L933.81875 486.6875A28.0125 28.0125 0 0 1 961.99999999 514.53125c0 15.35625-12.6 27.84375-28.12499999 27.84375zM483.36875 765.125L933.81875 765.125c15.58124999 0 28.125-12.4875 28.125-27.84375s-12.54375-27.84375-28.125-27.84375l-450.45 0c-15.58124999 0-28.125 12.4875-28.125 27.84375a28.0125 28.0125 0 0 0 28.125 27.84375z"  ></path></symbol></svg>';
    var script = function () {
        var scripts = document.getElementsByTagName("script");
        return scripts[scripts.length - 1]
    }();
    var shouldInjectCss = script.getAttribute("data-injectcss");
    var ready = function (fn) {
        if (document.addEventListener) {
            if (~["complete", "loaded", "interactive"].indexOf(document.readyState)) {
                setTimeout(fn, 0)
            } else {
                var loadFn = function () {
                    document.removeEventListener("DOMContentLoaded", loadFn, false);
                    fn()
                };
                document.addEventListener("DOMContentLoaded", loadFn, false)
            }
        } else if (document.attachEvent) {
            IEContentLoaded(window, fn)
        }

        function IEContentLoaded(w, fn) {
            var d = w.document,
                done = false,
                init = function () {
                    if (!done) {
                        done = true;
                        fn()
                    }
                };
            var polling = function () {
                try {
                    d.documentElement.doScroll("left")
                } catch (e) {
                    setTimeout(polling, 50);
                    return
                }
                init()
            };
            polling();
            d.onreadystatechange = function () {
                if (d.readyState == "complete") {
                    d.onreadystatechange = null;
                    init()
                }
            }
        }
    };
    var before = function (el, target) {
        target.parentNode.insertBefore(el, target)
    };
    var prepend = function (el, target) {
        if (target.firstChild) {
            before(el, target.firstChild)
        } else {
            target.appendChild(el)
        }
    };

    function appendSvg() {
        var div, svg;
        div = document.createElement("div");
        div.innerHTML = svgSprite;
        svgSprite = null;
        svg = div.getElementsByTagName("svg")[0];
        if (svg) {
            svg.setAttribute("aria-hidden", "true");
            svg.style.position = "absolute";
            svg.style.width = 0;
            svg.style.height = 0;
            svg.style.overflow = "hidden";
            prepend(svg, document.body)
        }
    }
    if (shouldInjectCss && !window.__iconfont__svg__cssinject__) {
        window.__iconfont__svg__cssinject__ = true;
        try {
            document.write("<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>")
        } catch (e) {
            console && console.log(e)
        }
    }
    ready(appendSvg)
})(window);